package com.flyaudio.xiaopengautopilot.center;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import com.flyaudio.xiaopengautopilot.R;
import com.flyaudio.xiaopengautopilot.constant.JSONKeyName;
import com.flyaudio.xiaopengautopilot.constant.ModuleKey;
import com.flyaudio.xiaopengautopilot.presenter.IVehicleModule;
import com.flyaudio.xiaopengautopilot.util.ByteUtil;
import com.flyaudio.xiaopengautopilot.util.JSONUtil;
import com.flyaudio.xiaopengautopilot.util.L;

public class VehicleService extends Service {
    private final String TAG = "VehicleService";

    private IVehicleModule mModule;
    public static VehicleService service;

    private HandleServiceMsg mServiceMsgHandler;
    public static final int MESSAGE_TRANSPARENT_CHANNEL = 0xF9;
    public static final int MESSAGE_TRANSPARENT_CHANNEL_TO_MOUDLE = 0xF8;
    private static final String FLY_SERVICE_ACTION = "cn.flyaudio.android.flyaudioservice.IFlyService";
    public static boolean bootsta=false;
    private boolean connectedSta=false;
    private final byte[] start_paramBuf ={(byte) 0x82,0x01,0x01};
    private final byte[] stop_paramBuf ={(byte) 0x82,0x01,0x00};

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        mModule = IVehicleModule.getInstance();
        service = this;
        L.d(TAG, "onCreate");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "****Service";
            String channelName = "**服务";
            int importance = NotificationManager.IMPORTANCE_LOW;
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            manager.createNotificationChannel(channel);
            Notification notification = new Notification.Builder(this, channelId)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("*****服务")
                    .setContentText("随时准备接收消息...")
                    .setAutoCancel(true)
                    .setShowWhen(true)
                    .build();
            int id = 10011;
            startForeground(id, notification);
        }

        mHandler.removeCallbacks(r);
        mHandler.postDelayed(r, 2000);
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

    Handler mHandler = new Handler();
    Runnable r = new Runnable() {
        @Override
        public void run() {
            if(connectedSta==false) {
                Component();
            }else{
                if (bootsta) {
//                    MakeAndSendMessage(stop_paramBuf);
                } else {
//                    MakeAndSendMessage(start_paramBuf);
                }
            }
            mHandler.postDelayed(this, 1000);
        }
    };

    public void onDataCallback(byte[] buf) {
        L.v(TAG, "onDataCallback " + ByteUtil.bytes2HexString(buf));
        //截取掉 0xff 0x55 len checksum
        byte[] targets = new byte[buf.length - 4];
        System.arraycopy(buf, 3, targets, 0, buf.length - 4);
        if (mModule != null)
            mModule.dealData(targets);
    }

    /**
     * 来自UIService的消息 通过Messager传输
     */
    private Messenger mService = null;
    private Messenger mMessenger = null;
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            connectedSta = true;
            mService = new Messenger(service);
            L.d(TAG, "onServiceConnected");
            try {
                Message msg = Message.obtain(null, MESSAGE_TRANSPARENT_CHANNEL);
                msg.replyTo = mMessenger;
                mService.send(msg);
                syncBcmStatusData(1);
                JSONUtil.getInstance().updateJson(JSONKeyName.AutoLightThumbX,316);
                syncInitStatusToMcu();
                senVaildHandler.postDelayed(r,500);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        Handler senVaildHandler = new Handler();
        Runnable r = new Runnable() {
            @Override
            public void run() {
                syncBcmStatusData(0);
            }
        };

        public void onServiceDisconnected(ComponentName className) {
            connectedSta=false;
            L.d(TAG, "onServiceDisconnected");
            if (mService == null) {
                try {
                    Message msg = Message.obtain(null, MESSAGE_TRANSPARENT_CHANNEL_TO_MOUDLE);
                    msg.replyTo = mMessenger;
                    mService.send(msg);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    };

    //连接服务
    public void Component() {
        mServiceMsgHandler = new HandleServiceMsg();
        mMessenger = new Messenger(mServiceMsgHandler);
        Intent serviceIntent = new Intent(FLY_SERVICE_ACTION);
        serviceIntent.setComponent(new ComponentName("cn.flyaudio.android.flyaudioservice", "cn.flyaudio.android.flyaudioservice.FlyService"));
        bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * 下发msg到FlyService
     * @param frameType 0: 标准帧 1:扩展帧
     * @param param 数据
     */
    public void MakeAndSendMessage(int frameType, byte[] param) {
        int sendbufLen = 9 + param.length+1;
        if (sendbufLen > 512||mService==null)
            return;
        int ControlID = 0x20ffff;
        byte ControlType = (byte) 0xff;
        byte[] sendbuf = new byte[sendbufLen];
        sendbuf[0] = (byte) 0xff;
        sendbuf[1] = 0x55;
        sendbuf[2] = (byte) (param.length + 6);
        sendbuf[3] = (byte) ((ControlID >> 24) & 0xff);
        sendbuf[4] = (byte) ((ControlID >> 16) & 0xff);
        sendbuf[5] = (byte) ((ControlID >> 8) & 0xff);
        sendbuf[6] = (byte) (ControlID & 0xff);
        sendbuf[7] = ControlType;
        if(frameType == 0) {
            sendbuf[8] = 0x08;
        }else {
            sendbuf[8] = (byte) 0x88;
        }
        for (int i = 0; i < param.length; i++) {
            sendbuf[9 + i] = param[i];
        }
        sendbuf[sendbufLen-1] = 0x00;
        Message msg = Message.obtain(null, MESSAGE_TRANSPARENT_CHANNEL_TO_MOUDLE);
        msg.replyTo = mMessenger;
        Bundle bundle = new Bundle();
        bundle.putByteArray("data", sendbuf);
        bundle.putInt("len", sendbufLen);
        msg.setData(bundle);
        L.d(TAG,"MakeAndSendMessage: " + ByteUtil.bytes2HexString(sendbuf));
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 发送电耗数据
     * @param param
     */
    public void MakePowerAndSendMessage(int functionType,byte[] param) {
        int sendbufLen = 9 + param.length+1;
        if (sendbufLen > 512||mService==null)
            return;
        int ControlID = 0x20fffe;
        byte ControlType = (byte) 0xff;
        byte[] sendbuf = new byte[sendbufLen];
        sendbuf[0] = (byte) 0xff;
        sendbuf[1] = 0x55;
        sendbuf[2] = (byte) (param.length + 6);
        sendbuf[3] = (byte) ((ControlID >> 24) & 0xff);
        sendbuf[4] = (byte) ((ControlID >> 16) & 0xff);
        sendbuf[5] = (byte) ((ControlID >> 8) & 0xff);
        sendbuf[6] = (byte) (ControlID & 0xff);
        sendbuf[7] = ControlType;
        sendbuf[8] =  (byte) functionType;
        for (int i = 0; i < param.length; i++) {
            sendbuf[9 + i] = param[i];
        }
        sendbuf[sendbufLen-1] = 0x00;

        Message msg = Message.obtain(null, MESSAGE_TRANSPARENT_CHANNEL_TO_MOUDLE);
        msg.replyTo = mMessenger;
        Bundle bundle = new Bundle();
        bundle.putByteArray("data", sendbuf);
        bundle.putInt("len", sendbufLen);
        msg.setData(bundle);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void syncBcmStatusData(int validVal) {
        byte[] mSendData = {0x06, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        int lowBeanLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.LowBeanLight,0);
        int frontTailLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.FrontTailLight,0);
        int autoLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.AutoLight,0);
        int rearFogLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearFogLight,0);
        int rearTailLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearTailLight,0);
        int driverSeatWindLV = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.DriverSeatWindLV,0);
        int driverSeatWarm_LV = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.DriverSeatWarm_LV,0);
        int fontWiperGear = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.FontWiperGear,0);
        int rearWiper = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearWiper,0);
        int rearMidSafetyBelt = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearMidSafetyBelt,0);
        int rearLeftSafetyBelt = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearLeftSafetyBelt,0);
        int rearRightSafetyBelt = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.RearRightSafetyBelt,0);
        int walkWarnSw = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.WalkWarnSw,0);
        int walkWarnVoice = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.WalkWarnVoice,0);
        int goHomeLight = (int) JSONUtil.getInstance().getMileageJSON(JSONKeyName.GoHomeLight,0);

        if(lowBeanLight == 0 && frontTailLight == 1) {
            lowBeanLight = 1;
        }
        int rSafetyBeltWarnSw = 0;
        if(rearMidSafetyBelt == 1 && rearLeftSafetyBelt == 1 && rearRightSafetyBelt == 1) {
            rSafetyBeltWarnSw = 0;
        }else {
            rSafetyBeltWarnSw = 1;
        }

        mSendData[2] = (byte) ( (lowBeanLight << 1) | (autoLight << 2) | (frontTailLight << 3) | (goHomeLight << 4) | (driverSeatWindLV << 5));
        mSendData[3] = (byte) (driverSeatWarm_LV | (fontWiperGear << 3) | (rearFogLight << 5) | (rearTailLight << 6) | (rearWiper << 7));
        mSendData[7] = (byte) validVal;
        mSendData[8] = (byte) ((walkWarnSw << 3) | (walkWarnVoice << 4));
        mSendData[9] = (byte) ( (rSafetyBeltWarnSw << 3));
        MakeAndSendMessage(0,mSendData);
        L.d(TAG,"syncBcmStatusData: " + ByteUtil.bytes2HexString(mSendData));
    }

    /**
     * 同步初始化状态
     */
    private void syncInitStatusToMcu() {
        byte[] sendbuf = {(byte) 0xff, 0x55, 0x07, 0x00, 0x20, (byte) 0xff, (byte) 0xfe, (byte) 0xff, (byte) 0x80, (byte) 0xff, 0x02, 0x00};

        Message msg = Message.obtain(null, MESSAGE_TRANSPARENT_CHANNEL_TO_MOUDLE);
        msg.replyTo = mMessenger;
        Bundle bundle = new Bundle();
        bundle.putByteArray("data", sendbuf);
        bundle.putInt("len", sendbuf.length);
        msg.setData(bundle);
        L.d(TAG,"syncInitStatusToMcu: " + ByteUtil.bytes2HexString(sendbuf));
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
